package com.game.game.service.team;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.protobuf.GeneratedMessage;
import com.game.common.Transmitter;
import com.game.common.constants.GlobalConstants;
import com.game.core.db.service.proxy.EntityProxyFactory;
import com.game.core.net.common.RemoteNode;
import com.game.core.service.PublicService;
import com.game.core.service.ServiceContainer;
import com.game.dbpersistence.game.entity.AccountEntity;
import com.game.dbpersistence.game.entity.FashionEntity;
import com.game.dbpersistence.game.entity.ItemEntity;
import com.game.dbpersistence.game.entity.MissionEntity;
import com.game.dbpersistence.game.entity.TeamEntity;
import com.game.dbpersistence.game.entity.WeaponEntity;
import com.game.dbpersistence.game.entity.WeaponsetEntity;
import com.game.game.GameServer;
import com.game.game.config.FashionConfig;
import com.game.game.config.ItemConfig;
import com.game.game.config.WeaponConfig;
import com.game.game.config.WeaponStrengthenConfig;
import com.game.game.config.XMLTemplateService;
import com.game.game.service.account.AccountLoginService;
import com.game.game.service.item.ItemService;
import com.game.game.service.server.ServerService;
import com.game.game.service.weapon.WeaponService;
import com.game.message.proto.battle.BattleProtoBuf.BGSingleGameOverRES;
import com.game.message.proto.battle.BattleProtoBuf.BGTeamGameOverRES;
import com.game.message.proto.battle.BattleProtoBuf.MAchieveItem;
import com.game.message.proto.item.ItemProtoBuf;
import com.game.message.proto.item.ItemProtoBuf.MItemInfo;
import com.game.message.proto.mission.MissionProtoBuf.MMissionInfo;
import com.game.message.proto.player.PlayerProtoBuf.PlayerInfo;
import com.game.message.proto.team.TeamProtoBuf.BGStartSingleBattleRES;
import com.game.message.proto.team.TeamProtoBuf.BGStartTeamBattleRES;
import com.game.message.proto.team.TeamProtoBuf.GBStartSingleBattleREQ;
import com.game.message.proto.team.TeamProtoBuf.GBStartTeamBattleREQ;
import com.game.message.proto.team.TeamProtoBuf.GBTmpDestoryRoomREQ;
import com.game.message.proto.team.TeamProtoBuf.GWChangeTeamPlayerStatusRES;
import com.game.message.proto.team.TeamProtoBuf.GWCreateTeamRES;
import com.game.message.proto.team.TeamProtoBuf.GWFinishBattleRES;
import com.game.message.proto.team.TeamProtoBuf.GWGetTeamInfoRES;
import com.game.message.proto.team.TeamProtoBuf.GWGetTeamListRES;
import com.game.message.proto.team.TeamProtoBuf.GWJoinTeamRES;
import com.game.message.proto.team.TeamProtoBuf.GWKickTeamMemberRES;
import com.game.message.proto.team.TeamProtoBuf.GWLeaveTeamRES;
import com.game.message.proto.team.TeamProtoBuf.GWModifyTeamRES;
import com.game.message.proto.team.TeamProtoBuf.GWQuickJoinTeamRES;
import com.game.message.proto.team.TeamProtoBuf.GWStartSingleBattleRES;
import com.game.message.proto.team.TeamProtoBuf.GWStartTeamBattleRES;
import com.game.message.proto.team.TeamProtoBuf.MSingleBattleInfo;
import com.game.message.proto.team.TeamProtoBuf.TeamInfo;
import com.game.message.proto.team.TeamProtoBuf.TeamPlayerInfo;
import com.game.message.proto.team.TeamProtoBuf.WGChangeTeamPlayerStatusREQ;
import com.game.message.proto.team.TeamProtoBuf.WGCreateTeamREQ;
import com.game.message.proto.team.TeamProtoBuf.WGGetTeamInfoREQ;
import com.game.message.proto.team.TeamProtoBuf.WGGetTeamListREQ;
import com.game.message.proto.team.TeamProtoBuf.WGJoinTeamREQ;
import com.game.message.proto.team.TeamProtoBuf.WGKickTeamMemberREQ;
import com.game.message.proto.team.TeamProtoBuf.WGLeaveTeamREQ;
import com.game.message.proto.team.TeamProtoBuf.WGModifyTeamREQ;
import com.game.message.proto.team.TeamProtoBuf.WGQuickJoinTeamREQ;
import com.game.message.proto.team.TeamProtoBuf.WGStartSingleBattleREQ;
import com.game.message.proto.team.TeamProtoBuf.WGStartTeamBattleREQ;
import com.game.message.proto.weapon.WeaponProtoBuf.WeaponInfo;
import com.game.message.protocol.ProtocolsConfig;

public class TeamService extends PublicService{

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private static Logger logger = LoggerFactory.getLogger(TeamService.class);
	public void sendMesToRemoteNode(RemoteNode remoteNode, GeneratedMessage message) {
		Transmitter.getInstance().write(remoteNode, GlobalConstants.DEFAULT_CALLBACK, message);
	}
	
	enum TeamState {
		/*空闲*/
		FREE,
		/*战斗中*/
		BATTLE	
	}
	
	enum MemberState {
		/*空闲*/
		FREE,
		/*准备*/
		READY,
		/*更换装备*/
		CHANGING_WEAPON
	}
	
	public void getTeamList(RemoteNode remoteNode, WGGetTeamListREQ req, int callback) {
		String account = req.getAccount();
		int missionId = req.getMissionId();
		List<TeamEntity> teamList = GameServer.teamEntityService.getTeamList(missionId);

		GWGetTeamListRES.Builder sendBuilder = GWGetTeamListRES.newBuilder(); 
		sendBuilder.setAccount(account);
		if ((teamList!=null) && (teamList.size() > 0)) {
			for (TeamEntity teamEntity : teamList) {
				// 满员队伍过滤
				if (teamEntity.getCurPlayerNum() < teamEntity.getMaxPlayerNum() && teamEntity.getStatus() == TeamState.FREE.ordinal()) {
					TeamInfo.Builder teamInfo = teamEntity.toProto();
					HashMap<String, String> teamMemberMap = teamEntity.getTeamPlayerInfos();
					for (String teamMemberAcc : teamMemberMap.keySet()) {
						TeamPlayerInfo.Builder teamPlayerInfo = this.getTeamPlayerInfo(teamMemberAcc, teamMemberMap.get(teamMemberAcc));
						teamInfo.addTeamPlayerInfos(teamPlayerInfo);
					}
					sendBuilder.addTeamInfos(teamInfo);
				}
			}
		}
		this.sendMesToRemoteNode(remoteNode, sendBuilder.build());
	}
	
	public void getTeamInfo(RemoteNode remoteNode, WGGetTeamInfoREQ req, int callback) {
		String account = req.getAccount();
		int missionId = req.getMissionId();
		long teamId = req.getTeamId();
		TeamEntity teamEntity = GameServer.teamEntityService.getTeam(missionId, teamId);
		this.broadcastTeamInfo(account, remoteNode, teamEntity);
	}
	
	public void broadcastTeamInfo(String account, RemoteNode remoteNode, TeamEntity teamEntity) {
		GWGetTeamInfoRES.Builder sendBuilder = GWGetTeamInfoRES.newBuilder(); 
		sendBuilder.setAccount(account);
		if(teamEntity!=null) {
			sendBuilder.setTeamInfo(this.getTeamInfo(teamEntity));
		}
		this.sendMesToRemoteNode(remoteNode, sendBuilder.build());
	}
	
	public TeamInfo.Builder getTeamInfo(TeamEntity teamEntity) {
		TeamInfo.Builder teamInfo = teamEntity.toProto();
		HashMap<String, String> teamMemberMap = teamEntity.getTeamPlayerInfos();
		for (String teamMemberAcc : teamMemberMap.keySet()) {
			TeamPlayerInfo.Builder teamPlayerInfo = this.getTeamPlayerInfo(teamMemberAcc, teamMemberMap.get(teamMemberAcc));
			teamInfo.addTeamPlayerInfos(teamPlayerInfo);
		}
		return teamInfo;
	}
	
	public void joinTeam(RemoteNode remoteNode, WGJoinTeamREQ req, int callback) {
		int result = this.joinTeam(remoteNode, req.getAccount(), req.getMissionId(), req.getTeamId());
		GWJoinTeamRES.Builder sendBuilder = GWJoinTeamRES.newBuilder(); 
		sendBuilder.setAccount(req.getAccount());
		sendBuilder.setResult(result);
		this.sendMesToRemoteNode(remoteNode, sendBuilder.build());
	}
	
	public int joinTeam(RemoteNode remoteNode, String account, int missionId, long teamId) {
		int result = ProtocolsConfig.JOIN_TEAM_FAIL;
		try {
			TeamEntity teamEntity = GameServer.teamEntityService.getTeam(missionId, teamId);
			if (teamEntity.getStatus() == TeamState.BATTLE.ordinal()) {
				result = ProtocolsConfig.TEAM_IN_BATTLE;
			}else if ((teamEntity != null)&&(teamEntity.getCurPlayerNum() >= teamEntity.getMaxPlayerNum())) {
				result = ProtocolsConfig.TEAM_FULL;
			}else if ((teamEntity != null)&&(teamEntity.getCurPlayerNum() < teamEntity.getMaxPlayerNum())) {
				EntityProxyFactory entityProxyFactory = new EntityProxyFactory();
				TeamEntity proxyTeam = entityProxyFactory.createProxyEntity(teamEntity);
				proxyTeam.setCurPlayerNum(teamEntity.getCurPlayerNum() + 1);
				HashMap<String, String> teamPlayerInfos = proxyTeam.getTeamPlayerInfos();
				teamPlayerInfos.put(account, Integer.toString(MemberState.FREE.ordinal()));
				proxyTeam.setTeamPlayerInfos(teamPlayerInfos);
				boolean ret = GameServer.teamEntityService.updateTeam(proxyTeam);
				if (ret) {
					//Broadcast
					for (String tmpAccount : teamPlayerInfos.keySet()) {
						this.broadcastTeamInfo(tmpAccount, remoteNode, proxyTeam);
					}
					AccountEntity accountEntity = GameServer.accountEntityService.getAccount(account);
					if (accountEntity != null) {
						EntityProxyFactory entityProxyFactory1 = new EntityProxyFactory();
						AccountEntity proxyAccount = entityProxyFactory1.createProxyEntity(accountEntity);
						proxyAccount.setMissionId(missionId);
						proxyAccount.setTeamId(teamId);
						ret = GameServer.accountEntityService.updateAccount(proxyAccount);
						if (!ret) {
							logger.error("TeamService joinTeam updateAccount() Filed ! accountEntity={}", accountEntity.toString());
						} else {
							result = ProtocolsConfig.JOIN_TEAM_SUCCESS;
						}
					}
				}else {
					logger.error("TeamService joinTeam updateTeam() Filed ! teamEntity={}", teamEntity.toString());
				}
			}
		} catch (Exception e) {
			//e.printStackTrace();
			logger.error("TeamService joinTeam updateTeam() Filed ! Exception err={}", e.toString());
		}
		return result;
	}
	
	public void quickJoinTeam(RemoteNode remoteNode, WGQuickJoinTeamREQ req, int callback) {
		List<TeamEntity> teamEntityList = GameServer.teamEntityService.getTeamList(req.getMissionId());
		int result = ProtocolsConfig.JOIN_TEAM_FAIL;
		for (TeamEntity teamEntity: teamEntityList) {
			result = this.joinTeam(remoteNode, req.getAccount(), teamEntity.getMissionId(), teamEntity.getId());
			if (result == ProtocolsConfig.JOIN_TEAM_SUCCESS) break;
		}
		GWQuickJoinTeamRES.Builder sendBuilder = GWQuickJoinTeamRES.newBuilder();
		sendBuilder.setAccount(req.getAccount());
		sendBuilder.setResult(result);
		this.sendMesToRemoteNode(remoteNode, sendBuilder.build());
	}
	
	public void createTeam(RemoteNode remoteNode, WGCreateTeamREQ req, int callback) {
		int result = ProtocolsConfig.CREATE_TEAM_FAIL;;
		long teamId = 0l;
		List<TeamEntity> teamList = new ArrayList<TeamEntity>();
		TeamEntity teamEntity = new TeamEntity();
		teamEntity.setMissionId(req.getMissionId());
		teamEntity.setCaptainId(req.getAccount());
		teamEntity.setTeamName(req.getTeamName());
		teamEntity.setMaxPlayerNum(req.getMaxPlayerNum());
		teamEntity.setCurPlayerNum(1);
		teamEntity.setTeamPwd(req.getPassword());
		teamEntity.setRequirePower(req.getRequirePower());
		teamEntity.setStatus(TeamState.FREE.ordinal());
		HashMap<String, String> teamPlayerInfos = new HashMap<String, String>();
		teamPlayerInfos.put(req.getAccount(), Integer.toString(MemberState.FREE.ordinal()));
		teamEntity.setTeamPlayerInfos(teamPlayerInfos);
		teamList.add(teamEntity);
		try {
			List<Long> rets = GameServer.teamEntityService.insertTeamList(teamList);
			if (rets != null) {
				for (Long ret : rets) {
					if (ret != 0) {
						result = ProtocolsConfig.CREATE_TEAM_SUCCESS;
						teamId = teamEntity.getId();
						AccountEntity accountEntity = GameServer.accountEntityService.getAccount(req.getAccount());
						if (accountEntity != null) {
							EntityProxyFactory entityProxyFactory1 = new EntityProxyFactory();
							AccountEntity proxyAccount = entityProxyFactory1.createProxyEntity(accountEntity);
							proxyAccount.setMissionId(req.getMissionId());
							proxyAccount.setTeamId(teamId);
							if (!GameServer.accountEntityService.updateAccount(proxyAccount)) {
								logger.error("TeamService joinTeam updateAccount() Filed ! accountEntity={}",
										accountEntity.toString());
							}
						}
					} else {
						logger.error("TeamService createTeam insertTeamList() Filed ! teamEntity={}",
								teamList.get(0).toString());
					}
				}
			}
		} catch (Exception e) {
			// e.printStackTrace();
			logger.error("TeamService joinTeam updateTeam() Filed ! Exception err={}", e.toString());
		}
		GWCreateTeamRES.Builder sendBuilder = GWCreateTeamRES.newBuilder(); 
		sendBuilder.setAccount(req.getAccount());
		sendBuilder.setResult(result);
		sendBuilder.setTeamId(teamId);
		this.sendMesToRemoteNode(remoteNode, sendBuilder.build());
	}
	
	public void modifyTeam(RemoteNode remoteNode, WGModifyTeamREQ req, int callback) {
		int result = ProtocolsConfig.MODIFY_TEAM_FAIL;
		try {
			TeamEntity teamEntity = GameServer.teamEntityService.getTeam(req.getMissionId(), req.getTeamId());
			if ((teamEntity != null) && req.getAccount().equalsIgnoreCase(teamEntity.getCaptainId())) {
				EntityProxyFactory entityProxyFactory = new EntityProxyFactory();
				TeamEntity proxyTeam = entityProxyFactory.createProxyEntity(teamEntity);
				if (req.getTeamName() != null && req.getTeamName() != "") proxyTeam.setTeamName(req.getTeamName());
				if (req.getPassword() != null && req.getPassword() != "") proxyTeam.setTeamPwd(req.getPassword());
				proxyTeam.setRequirePower(req.getRequirePower() >= 0 ? req.getRequirePower() : 0);
				boolean ret = GameServer.teamEntityService.updateTeam(proxyTeam);
				if (ret) {
					result = ProtocolsConfig.MODIFY_TEAM_SUCCESS;
					// Broadcast
					for (String account :proxyTeam.getTeamPlayerInfos().keySet()) {
						this.broadcastTeamInfo(account, remoteNode, proxyTeam);
					}
				}
			}
		} catch (Exception e) {
			// e.printStackTrace();
			logger.error("TeamService kickTeamMember updateTeam() Filed ! ", e.toString());
		}
		GWModifyTeamRES.Builder sendBuilder = GWModifyTeamRES.newBuilder();
		sendBuilder.setAccount(req.getAccount());
		sendBuilder.setResult(result);
		this.sendMesToRemoteNode(remoteNode, sendBuilder.build());
	}
	
	public void kickTeamMember(RemoteNode remoteNode, WGKickTeamMemberREQ req, int callback) {
		int result = ProtocolsConfig.KICK_TEAM_MEMBER_FAIL;
		try {
			TeamEntity teamEntity = GameServer.teamEntityService.getTeam(req.getMissionId(), req.getTeamId());
			// 踢人的必须是队长而且不能自己踢自己
			if ((teamEntity != null) && (req.getAccount().equalsIgnoreCase(teamEntity.getCaptainId()))
					&& (!req.getAccount().equalsIgnoreCase(req.getKickAccount()))) {
				EntityProxyFactory entityProxyFactory = new EntityProxyFactory();
				TeamEntity proxyTeam = entityProxyFactory.createProxyEntity(teamEntity);
				proxyTeam.setCurPlayerNum(teamEntity.getCurPlayerNum() - 1);
				HashMap<String, String> teamPlayerInfos = teamEntity.getTeamPlayerInfos();
				teamPlayerInfos.remove(req.getKickAccount());
				proxyTeam.setTeamPlayerInfos(teamPlayerInfos);
				boolean ret = GameServer.teamEntityService.updateTeam(proxyTeam);
				if (ret) {
					result = ProtocolsConfig.KICK_TEAM_MEMBER_SUCCESS;
					// Broadcast
					for (String account : teamPlayerInfos.keySet()) {
						this.broadcastTeamInfo(account, remoteNode, proxyTeam);
					}
					this.broadcastTeamInfo(req.getKickAccount(), remoteNode, proxyTeam);
					AccountEntity accountEntity = GameServer.accountEntityService.getAccount(req.getKickAccount());
					if (accountEntity != null) {
						EntityProxyFactory entityProxyFactory1 = new EntityProxyFactory();
						AccountEntity proxyAccount = entityProxyFactory1.createProxyEntity(accountEntity);
						proxyAccount.setMissionId(0);
						proxyAccount.setTeamId(0);
						if (!GameServer.accountEntityService.updateAccount(proxyAccount)) {
							logger.error("TeamService joinTeam updateAccount() Filed ! accountEntity={}",
									accountEntity.toString());
						}
					}
				} else {
					logger.error("TeamService kickTeamMember updateTeam() Filed ! teamEntity={}", teamEntity.toString());
				}
			}
		} catch (Exception e) {
			// e.printStackTrace();
			logger.error("TeamService kickTeamMember updateTeam() Filed ! Exception err={}", e.toString());
		}
		GWKickTeamMemberRES.Builder sendBuilder = GWKickTeamMemberRES.newBuilder(); 
		sendBuilder.setAccount(req.getAccount());
		sendBuilder.setResult(result);
		this.sendMesToRemoteNode(remoteNode, sendBuilder.build());
	}
	
	public void changeTeamPlayerStatus(RemoteNode remoteNode, WGChangeTeamPlayerStatusREQ req, int callback) {
		int result = ProtocolsConfig.CHANGE_TEAM_PLAYER_STATUS_FAIL;
		try {
			TeamEntity teamEntity = GameServer.teamEntityService.getTeam(req.getMissionId(), req.getTeamId());
			if (teamEntity != null) {
				HashMap<String, String> teamPlayerInfos = teamEntity.getTeamPlayerInfos();
				if (teamPlayerInfos.containsKey(req.getAccount())) {
					EntityProxyFactory entityProxyFactory = new EntityProxyFactory();
					TeamEntity proxyTeam = entityProxyFactory.createProxyEntity(teamEntity);
					teamPlayerInfos.put(req.getAccount(), String.valueOf(req.getChangeStatus()));
					proxyTeam.setTeamPlayerInfos(teamPlayerInfos);
					boolean ret = GameServer.teamEntityService.updateTeam(proxyTeam);
					if (ret) {
						result = ProtocolsConfig.CHANGE_TEAM_PLAYER_STATUS_SUCCESS;
						// Broadcast
						for (String account : teamPlayerInfos.keySet()) {
							this.broadcastTeamInfo(account, remoteNode, proxyTeam);
						}
					} else {
						logger.error("TeamService changeTeamPlayerStatus updateTeam() Filed ! teamEntity={}",
								teamEntity.toString());
					}
				}
			}
		} catch (Exception e) {
			// e.printStackTrace();
			logger.error("TeamService changeTeamPlayerStatus updateTeam() Filed ! Exception err={}", e.toString());
		}
		GWChangeTeamPlayerStatusRES.Builder sendBuilder = GWChangeTeamPlayerStatusRES.newBuilder(); 
		sendBuilder.setAccount(req.getAccount());
		sendBuilder.setResult(result);
		this.sendMesToRemoteNode(remoteNode, sendBuilder.build());
	}
	
	public void startTeamBattle(RemoteNode remoteNode, WGStartTeamBattleREQ req, int callback) {
		try {
			TeamEntity teamEntity = GameServer.teamEntityService.getTeam(req.getMissionId(), req.getTeamId());
			if (teamEntity != null) {
				if (this.checkAllReady(teamEntity)) {
					EntityProxyFactory entityProxyFactory = new EntityProxyFactory();
					TeamEntity proxyTeam = entityProxyFactory.createProxyEntity(teamEntity);
					proxyTeam.setStatus(TeamState.BATTLE.ordinal());
					boolean ret = GameServer.teamEntityService.updateTeam(proxyTeam);
					// 通知battle
					GBStartTeamBattleREQ.Builder sendBuilder = GBStartTeamBattleREQ.newBuilder();
					sendBuilder.setAccount(req.getAccount());
					sendBuilder.setTeamInfo(this.getTeamInfo(teamEntity));
					ServerService service = ServiceContainer.getInstance().getPublicService(ServerService.class);
					this.sendMesToRemoteNode(service.getBattleNode(2000), sendBuilder.build());
				} else {
					logger.error("TeamService startTeamBattle checkAllReady() Filed ! teamEntity={}",
							teamEntity.toString());
				}
			}
		} catch (Exception e) {
			// e.printStackTrace();
			logger.error("TeamService startTeamBattle updateTeam() Filed ! Exception err={}", e.toString());
		}
	}
	
	public void startTeamBattleResult(BGStartTeamBattleRES res) {
		TeamInfo teamInfo = res.getTeamInfo();
		int result = res.getResult();
		List<TeamPlayerInfo> teamPlayerInfoList = teamInfo.getTeamPlayerInfosList();
		ServerService service = ServiceContainer.getInstance().getPublicService(ServerService.class);
		RemoteNode remoteNode = service.getGatewayNode(3000);
		for (TeamPlayerInfo teamPlayerInfo : teamPlayerInfoList) {
			GWStartTeamBattleRES.Builder sendBuilder = GWStartTeamBattleRES.newBuilder();
			sendBuilder.setAccount(teamPlayerInfo.getId());
			sendBuilder.setResult(result);
			this.sendMesToRemoteNode(remoteNode, sendBuilder.build());
		}
	}
	
	public boolean checkAllReady(TeamEntity teamEntity) {
		HashMap<String, String> teamPlayerInfos = teamEntity.getTeamPlayerInfos();
		String captianId = teamEntity.getCaptainId();
		for (Map.Entry<String, String>teamPlayerInfo : teamPlayerInfos.entrySet()) {
			// 有队员不在准备状态
			if (!teamPlayerInfo.getKey().equals(captianId) && !Integer.toString(MemberState.READY.ordinal()).equals(teamPlayerInfo.getValue())) {
				return false;
			}
			// 有玩家没有穿戴装备
			List<WeaponInfo.Builder> weaponList = WeaponService.getCurrentWeaponList(teamPlayerInfo.getKey());
			if (weaponList.size() == 0) {
				return false;
			}
		}
		return true;
	}
	
	public void startSingleBattle(RemoteNode remoteNode, WGStartSingleBattleREQ req, int callback) {
		try {
			if (this.checkSingleReady(req.getAccount())) {
				// 通知battle
				GBStartSingleBattleREQ.Builder sendBuilder = GBStartSingleBattleREQ.newBuilder();
				sendBuilder.setAccount(req.getAccount());
				sendBuilder.setSingleBattleInfo(this.getMSingleBattleInfo(req.getAccount(), req.getMissionId()));
				ServerService service = ServiceContainer.getInstance().getPublicService(ServerService.class);
				this.sendMesToRemoteNode(service.getBattleNode(2000), sendBuilder.build());
			} else {
				logger.error("TeamService startSingleBattle Filed ! account = {}", req.getAccount());
			}
		} catch (Exception e) {
			// e.printStackTrace();
			logger.error("TeamService startSingleBattle Filed ! Exception err={}", e.toString());
		}
	}
	
	public void startSingleBattleResult(BGStartSingleBattleRES res) {
		ServerService service = ServiceContainer.getInstance().getPublicService(ServerService.class);
		RemoteNode remoteNode = service.getGatewayNode(3000);
		GWStartSingleBattleRES.Builder sendBuilder = GWStartSingleBattleRES.newBuilder();
		sendBuilder.setAccount(res.getAccount());
		sendBuilder.setResult(res.getResult());
		this.sendMesToRemoteNode(remoteNode, sendBuilder.build());
	}
	
	public boolean checkSingleReady(String account) {
		List<WeaponInfo.Builder> weaponList = WeaponService.getCurrentWeaponList(account);
		if (weaponList.size() == 0) {
			return false;
		}
		return true;
	}
	
	public void leaveTeam(RemoteNode remoteNode, WGLeaveTeamREQ req, int callback) {
		int result = ProtocolsConfig.LEAVE_TEAM_FAIL;
		try {
			TeamEntity teamEntity = GameServer.teamEntityService.getTeam(req.getMissionId(), req.getTeamId());
			if (teamEntity != null) {
				EntityProxyFactory entityProxyFactory = new EntityProxyFactory();
				TeamEntity proxyTeam = entityProxyFactory.createProxyEntity(teamEntity);
				proxyTeam.setCurPlayerNum(teamEntity.getCurPlayerNum() - 1);
				HashMap<String, String> teamPlayerInfos = teamEntity.getTeamPlayerInfos();
				teamPlayerInfos.remove(req.getAccount());
				// 如果队伍里面没有人了
				if (teamPlayerInfos.isEmpty()) {
					// 删除队伍
					boolean ret = GameServer.teamEntityService.deleteTeam(teamEntity);
					if (ret) {
						result = ProtocolsConfig.LEAVE_TEAM_SUCCESS;
						AccountEntity accountEntity = GameServer.accountEntityService.getAccount(req.getAccount());
						if (accountEntity != null) {
							EntityProxyFactory entityProxyFactory1 = new EntityProxyFactory();
							AccountEntity proxyAccount = entityProxyFactory1.createProxyEntity(accountEntity);
							proxyAccount.setMissionId(0);
							proxyAccount.setTeamId(0);
							if (!GameServer.accountEntityService.updateAccount(proxyAccount)) {
								logger.error("TeamService joinTeam updateAccount() Filed ! accountEntity={}",
										accountEntity.toString());
							}
						}
					}else {
						logger.error("TeamService leaveTeam deleteTeam() Filed ! teamEntity={}", teamEntity.toString());
					}
				} else {
					// 如果队伍里面还有人
					if (req.getAccount().equalsIgnoreCase(teamEntity.getCaptainId())) {
						// 如果离开队伍的人是队长
						for (String teamMemberAcc : teamPlayerInfos.keySet()) {
							proxyTeam.setCaptainId(teamMemberAcc);
							HashMap<String, String> tmpPlayerInfo = proxyTeam.getTeamPlayerInfos();
							tmpPlayerInfo.put(teamMemberAcc, Integer.toString(MemberState.FREE.ordinal()));
							break;
						}
					}
					proxyTeam.setTeamPlayerInfos(teamPlayerInfos);
					boolean ret = GameServer.teamEntityService.updateTeam(proxyTeam);
					if (ret) {
						result = ProtocolsConfig.LEAVE_TEAM_SUCCESS;
						// Broadcast
						for (String account : teamPlayerInfos.keySet()) {
							this.broadcastTeamInfo(account, remoteNode, proxyTeam);
						}
						AccountEntity accountEntity = GameServer.accountEntityService.getAccount(req.getAccount());
						if (accountEntity != null) {
							EntityProxyFactory entityProxyFactory1 = new EntityProxyFactory();
							AccountEntity proxyAccount = entityProxyFactory1.createProxyEntity(accountEntity);
							proxyAccount.setMissionId(0);
							proxyAccount.setTeamId(0);
							if (!GameServer.accountEntityService.updateAccount(proxyAccount)) {
								logger.error("TeamService joinTeam updateAccount() Filed ! accountEntity={}",
										accountEntity.toString());
							}
						}
					}else {
						logger.error("TeamService leaveTeam updateTeam() Filed ! teamEntity={}", teamEntity.toString());
					}
				}
			}
		} catch (Exception e) {
			// e.printStackTrace();
			logger.error("TeamService leaveTeam updateTeam() Filed ! Exception err={}", e.toString());
		}
		GWLeaveTeamRES.Builder sendBuilder = GWLeaveTeamRES.newBuilder(); 
		sendBuilder.setAccount(req.getAccount());
		sendBuilder.setResult(result);
		this.sendMesToRemoteNode(remoteNode, sendBuilder.build());
	}
	
	public void handleAfterTeamBattle(BGTeamGameOverRES res) {
		TeamEntity teamEntity = GameServer.teamEntityService.getTeam(res.getMissionId(), res.getTeamId());
		Map<String, String> memberMap = teamEntity.getTeamPlayerInfos();
		for (String account : memberMap.keySet()) {
			try {
				AccountEntity accountEntity = GameServer.accountEntityService.getAccount(account);
				EntityProxyFactory entityProxyFactory = new EntityProxyFactory();
				AccountEntity proxyAccount = entityProxyFactory.createProxyEntity(accountEntity);
				proxyAccount.setTeamId(0);
				proxyAccount.setMissionId(0);
				//解锁关卡
				if ("1".equals(res.getAchievement())) {
					this.completeMission(account, res.getMissionId(), res.getAchievement());
				}
				List<MItemInfo> dropItemsList = new ArrayList<MItemInfo>(); 
				for(MItemInfo itemInfo :res.getMonstersDropItemsList()) {
					dropItemsList.add(itemInfo);
				}
				for(MItemInfo itemInfo :res.getGamecopyDropItemsList()) {
					dropItemsList.add(itemInfo);
				}
				List<MItemInfo> achieveRewardItemsList = null;
				List<String> achievementList = null;
				for(MAchieveItem achieveItem : res.getAchieveItemsList()) {
					if(account.equals(achieveItem.getAccount())) {
						achievementList = achieveItem.getAchievementConditionList();
						achieveRewardItemsList = achieveItem.getAchieveRewardItemsList();
						for(MItemInfo itemInfo : achieveRewardItemsList) {
							dropItemsList.add(itemInfo);
						}
					}
				}
				saveAllDropItemsInRedisDB(account, dropItemsList);

				GWFinishBattleRES.Builder sendBuilder = GWFinishBattleRES.newBuilder();
				sendBuilder.setAccount(account);
				MMissionInfo.Builder missionInfo = MMissionInfo.newBuilder();
				missionInfo.setOwnerId(account);
				missionInfo.setMissionId(res.getMissionId());
				missionInfo.setAchievement(res.getAchievement());
				missionInfo.addAllAchievementCondition(achievementList);
				sendBuilder.setMissionInfo(missionInfo);
				sendBuilder.addAllMonstersDropItems(res.getMonstersDropItemsList());
				sendBuilder.addAllGamecopyDropItems(res.getGamecopyDropItemsList());
				sendBuilder.addAllAchievementDropItems(achieveRewardItemsList);
				ServerService service = ServiceContainer.getInstance().getPublicService(ServerService.class);
				RemoteNode remoteNode = service.getGatewayNode(3000);
				this.sendMesToRemoteNode(remoteNode, sendBuilder.build());
				if (!GameServer.accountEntityService.updateAccount(proxyAccount)) {
					logger.error("TeamService handleAfterTeamBattle updateAccount() Filed ! accountEntity={}",
							accountEntity.toString());
				}
			} catch (Exception e) {
				// e.printStackTrace();
				logger.error(e.toString());
			}
		}
		if (!GameServer.teamEntityService.deleteTeam(teamEntity)) {
			logger.error("TeamService handleAfterTeamBattle deleteTeam() Filed ! teamEntity={}",
					teamEntity.toString());
		}
	}
	
	public void handleAfterSingleBattle(BGSingleGameOverRES res) {
		//解锁关卡
		if ("1".equals(res.getAchievement())) {
			this.completeMission(res.getAccount(), res.getMissionId(), res.getAchievement());
		}
		
		List<MItemInfo> dropItemsList = new ArrayList<MItemInfo>(); 
		for(MItemInfo itemInfo :res.getMonstersDropItemsList()) {
			dropItemsList.add(itemInfo);
		}
		for(MItemInfo itemInfo :res.getGamecopyDropItemsList()) {
			dropItemsList.add(itemInfo);
		}
		for(MItemInfo itemInfo :res.getAchieveRewardItemsList()) {
			dropItemsList.add(itemInfo);
		}
		saveAllDropItemsInRedisDB(res.getAccount(), dropItemsList);
		
		GWFinishBattleRES.Builder sendBuilder = GWFinishBattleRES.newBuilder();
		sendBuilder.setAccount(res.getAccount());
		MMissionInfo.Builder missionInfo = MMissionInfo.newBuilder();
		missionInfo.setOwnerId(res.getAccount());
		missionInfo.setMissionId(res.getMissionId());
		missionInfo.setAchievement(res.getAchievement());
		missionInfo.addAllAchievementCondition(res.getAchievementConditionList());
		sendBuilder.setMissionInfo(missionInfo);
		sendBuilder.addAllMonstersDropItems(res.getMonstersDropItemsList());
		sendBuilder.addAllGamecopyDropItems(res.getGamecopyDropItemsList());
		sendBuilder.addAllAchievementDropItems(res.getAchieveRewardItemsList());
		ServerService service = ServiceContainer.getInstance().getPublicService(ServerService.class);
		RemoteNode remoteNode = service.getGatewayNode(3000);
		this.sendMesToRemoteNode(remoteNode, sendBuilder.build());
	}
	
	public void saveAllDropItemsInRedisDB(String account, List<MItemInfo> dropItemsList) {
		ItemService itemService = ServiceContainer.getInstance().getPublicService(ItemService.class);
		WeaponService weaponService = ServiceContainer.getInstance().getPublicService(WeaponService.class);
		AccountLoginService accountLoginService = ServiceContainer.getInstance().getPublicService(AccountLoginService.class);
		EntityProxyFactory entityProxyFactory = new EntityProxyFactory();
		AccountEntity accountEntity = GameServer.accountEntityService.getAccount(account);
		AccountEntity proxyAccount = null;
		if(accountEntity != null) {
			try {
				proxyAccount = entityProxyFactory.createProxyEntity(accountEntity);
			} catch (Exception e) {
				logger.error(e.toString());
			}
		}
		Map<Integer, Integer> dropItemsMap = new HashMap<>();
		for(MItemInfo itemInfo:dropItemsList) {
			if(itemInfo.getItemId() < 100000) {
				//货币
				if(proxyAccount != null) {
					if(itemInfo.getItemId() == 1) {
						proxyAccount.setExperience(proxyAccount.getExperience() + itemInfo.getCount());
					}else if(itemInfo.getItemId() == 2) {
						proxyAccount.setGoldCoin(proxyAccount.getGoldCoin() + itemInfo.getCount());
					}else if(itemInfo.getItemId() == 3) {
						proxyAccount.setDiamonds(proxyAccount.getDiamonds() + itemInfo.getCount());
					}else if(itemInfo.getItemId() == 4) {
						proxyAccount.setGiftCert(proxyAccount.getGiftCert() + itemInfo.getCount());
					}else if(itemInfo.getItemId() == 5) {
						proxyAccount.setFeats(proxyAccount.getFeats() + itemInfo.getCount());
					}
				}
				continue;
			}
			else if((itemInfo.getItemId() > 100000) && (itemInfo.getItemId() < 200000)) {
				//武器
				WeaponEntity weaponEntity = GameServer.weaponEntityService.getWeapon(account, itemInfo.getItemId());
				if (weaponEntity == null) {
					WeaponConfig weaponConfig = XMLTemplateService.weaponConfigMap.get(itemInfo.getItemId());
					if (weaponConfig != null) {
						int weaponId = itemInfo.getItemId();
						String weaponName = weaponConfig.getName();
						int weaponType = weaponConfig.getWeaponType();
						int weaponLevel = weaponConfig.getWeaponLevel();
						// int weaponMaxLevel = weaponConfig.getWeaponMaxLevel();
						int mainSkillId = weaponConfig.getMainSkillId();
		
						weaponEntity = new WeaponEntity();
						weaponEntity.setOwnerId(account);
						weaponEntity.setWeaponId(weaponId);
						weaponEntity.setName(weaponName);
						weaponEntity.setWeaponType(weaponType);
						weaponEntity.setWeaponLevel(weaponLevel);
						// weaponEntity.setWeaponMaxLevel(weaponMaxLevel);
						weaponEntity.setMainSkillId(mainSkillId);
						WeaponStrengthenConfig weaponStrengthenConfig = XMLTemplateService.weaponStrengthenConfigMap.get(itemInfo.getItemId());
						if ((weaponStrengthenConfig != null) && (weaponStrengthenConfig.getMainNodeList().size() > 0)) {
							weaponEntity.setMainNodeList(weaponStrengthenConfig.getMainNodeList());
						}
						long ret = GameServer.weaponEntityService.insertEntity(weaponEntity);
						if (ret > 0) {
							logger.info("Drop the Weapon insertEntity Success:" + weaponEntity.toString());
							weaponService.pushSynWeaponInfo(account, weaponEntity, ItemProtoBuf.SynItemType.DropItemsAdd.ordinal());
						} else {
							logger.error("Drop the Weapon insertEntity Error:" + weaponEntity.toString());
						}
					}
				}else {
					logger.error("Drop The Weapon Has Exist!!!:" + itemInfo.toString());
				}
				continue;
			}
			else if((itemInfo.getItemId() > 200000) && (itemInfo.getItemId() < 300000)) {
				//服装
				FashionEntity fashionEntity = GameServer.fashionEntityService.getFashion(account, itemInfo.getItemId());
				if (fashionEntity == null) {
					FashionConfig fashionConfig = XMLTemplateService.fashionConfigMap.get(itemInfo.getItemId());
					if (fashionConfig != null) {
						fashionEntity = new FashionEntity();
						fashionEntity.setOwnerId(account);
						fashionEntity.setFashionId(fashionConfig.getFashionId());
						fashionEntity.setUnlocked(fashionConfig.getStatus());
						fashionEntity.setHairColour(1);
						fashionEntity.setSkinColour(1);
						fashionEntity.setMainbodyColour(1);
						fashionEntity.setDecorateColour(1);
						fashionEntity.setSkinColours("[1]");
						fashionEntity.setHairColours("[1]");
						fashionEntity.setMainbodyColours("[1]");
						fashionEntity.setDecorateColours("[1]");
						
						long ret = GameServer.fashionEntityService.insertFashion(fashionEntity);
						if (ret > 0) {
							logger.info("Drop the Fashion insertFashion Success:" + fashionEntity.toString());
							weaponService.pushSynFashionInfo(account, fashionEntity, ItemProtoBuf.SynItemType.DropItemsAdd.ordinal());
						} else {
							logger.error("Drop the Fashion insertFashion Error:" + fashionEntity.toString());
						}
					}
				}else {
					logger.error("Drop The Fashion Has Exist!!!:" + itemInfo.toString());
				}
				continue;
			}
			else if((itemInfo.getItemId() > 300000) && (itemInfo.getItemId() < 400000)) {
				//道具
				ItemConfig itemConfig = XMLTemplateService.itemConfigMap.get(itemInfo.getItemId());
				if (itemConfig != null) {
					ItemEntity itemEntity = GameServer.itemEntityService.getItem(account, itemInfo.getItemId());
					if (itemEntity == null) {
						itemEntity = new ItemEntity(account, itemInfo.getItemId(), itemConfig.getType(), itemInfo.getCount());
						long ret = GameServer.itemEntityService.insertItem(itemEntity);
						if (ret > 0) {
							logger.info("Drop the Item insertItem Success:" + itemEntity.toString());
							dropItemsMap.put(itemInfo.getItemId(), itemInfo.getCount());
						} else {
							logger.error("Drop the Item insertItem Error:" + itemEntity.toString());
						}
					} else {
						try {
							//EntityProxyFactory entityProxyFactory = new EntityProxyFactory();
							ItemEntity itemProxyEntity = entityProxyFactory.createProxyEntity(itemEntity);
							itemProxyEntity.setCount(itemEntity.getCount() + itemInfo.getCount());
							boolean ret = GameServer.itemEntityService.updateItem(itemProxyEntity);
							if (ret) {
								logger.info("Drop the Item updateItem Success:" + itemProxyEntity.toString());
								int itemCnt = 0;
								if(dropItemsMap.containsKey(itemInfo.getItemId())) {
									itemCnt = dropItemsMap.get(itemInfo.getItemId());
								}
								dropItemsMap.put(itemInfo.getItemId(), itemInfo.getCount() + itemCnt);
							} else {
								logger.error("Drop the Item updateItem Error:" + itemProxyEntity.toString());
							}
						} catch(Exception e) {
							logger.error(e.toString());
						}
					}
				}else {
					logger.error("Drop The Item Has NoExist!!!:" + itemInfo.toString());
				}
				continue;
			}
			else{
				//未知物品
				continue;
			}
		}
		if((accountEntity!=null)&&(!accountEntity.equals(proxyAccount))){
			GameServer.accountEntityService.updateAccount(proxyAccount);
			accountLoginService.pushSynAccountInfo(account, proxyAccount, ItemProtoBuf.SynItemType.DropItemsAdd.ordinal());
		}
		if(dropItemsMap.size() > 0) {
			itemService.pushSynItemInfo(account, dropItemsMap, ItemProtoBuf.SynItemType.DropItemsAdd.ordinal());
		}
	}
	
	public void completeMission(String ownerId, int missionId, String achievement) {
		List<MissionEntity> missionList = GameServer.missionEntityService.getMissionList(ownerId);
		try {
			boolean isNew = true;
			for (MissionEntity mission : missionList) {
				if (mission.getMissionId() == missionId) {
					EntityProxyFactory entityProxyFactory = new EntityProxyFactory();
					MissionEntity proxyMissionEntity = entityProxyFactory.createProxyEntity(mission);
					proxyMissionEntity.setAchievement(achievement);
					GameServer.missionEntityService.updateEntity(proxyMissionEntity);
					isNew = false;
					break;
				}
			}
			if (isNew) {
				List<MissionEntity> newMissionList = new ArrayList<>();
				MissionEntity newMissionEntity = new MissionEntity();
				newMissionEntity.setOwnerId(ownerId);
				newMissionEntity.setMissionId(missionId);
				newMissionEntity.setAchievement(achievement);
				newMissionList.add(newMissionEntity);
				GameServer.missionEntityService.insertMissionList(newMissionList);
			}
		} catch(Exception e) {
			logger.error("completeMission error : Exception err={}" + e.toString());
		}
	}
	
	public TeamPlayerInfo.Builder getTeamPlayerInfo(String acc, String status) {
		TeamPlayerInfo.Builder teamPlayerInfo = TeamPlayerInfo.newBuilder();
		teamPlayerInfo.setId(acc);
		teamPlayerInfo.setStatus(Integer.parseInt(status));
		AccountEntity account = GameServer.accountEntityService.getAccount(acc);
		PlayerInfo.Builder playerInfo = PlayerInfo.newBuilder();
		playerInfo.setId(account.getUid());
		playerInfo.setAccount(account.getAcc());
		playerInfo.setName(account.getName());
		playerInfo.setSex(account.getSex());
		playerInfo.setLevel(account.getLevel());
		
		WeaponsetEntity weaponSetEntity = GameServer.weaponsetEntityService.getWeaponset(account.getAcc(), account.getWeaponSet());
		playerInfo.setWeaponSetInfo(weaponSetEntity.toProto());
		FashionEntity fashionEntity = GameServer.fashionEntityService.getFashion(account.getAcc(), weaponSetEntity.getFashionId());
		playerInfo.setFashionInfo(fashionEntity.toProto());
		List<WeaponInfo.Builder> weaponList = WeaponService.getCurrentWeaponList(acc);
		for (WeaponInfo.Builder tmpWeaponInfo : weaponList) {
			playerInfo.addWeaponInfos(tmpWeaponInfo);
		}
		teamPlayerInfo.setPlayerInfo(playerInfo);
		return teamPlayerInfo;
	}
	
	public MSingleBattleInfo.Builder getMSingleBattleInfo(String acc, int missionId) {
		AccountEntity account = GameServer.accountEntityService.getAccount(acc);
		PlayerInfo.Builder playerInfo = PlayerInfo.newBuilder();
		playerInfo.setId(account.getUid());
		playerInfo.setAccount(account.getAcc());
		playerInfo.setName(account.getName());
		playerInfo.setSex(account.getSex());
		playerInfo.setLevel(account.getLevel());
		WeaponsetEntity weaponSetEntity = GameServer.weaponsetEntityService.getWeaponset(account.getAcc(), account.getWeaponSet());
		playerInfo.setWeaponSetInfo(weaponSetEntity.toProto());
		FashionEntity fashionEntity = GameServer.fashionEntityService.getFashion(account.getAcc(), weaponSetEntity.getFashionId());
		playerInfo.setFashionInfo(fashionEntity.toProto());
		List<WeaponInfo.Builder> weaponList = WeaponService.getCurrentWeaponList(acc);
		for (WeaponInfo.Builder tmpWeaponInfo : weaponList) {
			playerInfo.addWeaponInfos(tmpWeaponInfo);
		}
		MSingleBattleInfo.Builder mSingleBattleInfoBuilder = MSingleBattleInfo.newBuilder();
		mSingleBattleInfoBuilder.setMissionId(missionId);
		mSingleBattleInfoBuilder.setPlayerInfo(playerInfo);
		return mSingleBattleInfoBuilder;
	}
	
	public void tmpDestoryRoom(long teamId, int missionId) {
		try {
			TeamEntity teamEntity = GameServer.teamEntityService.getTeam(missionId, teamId);
			if (teamEntity != null) {
				EntityProxyFactory entityProxyFactory = new EntityProxyFactory();
				TeamEntity proxyTeam = entityProxyFactory.createProxyEntity(teamEntity);
				proxyTeam.setCurPlayerNum(teamEntity.getCurPlayerNum() - 1);
				HashMap<String, String> teamPlayerInfos = teamEntity.getTeamPlayerInfos();
				for (String teamMemberAcc : teamPlayerInfos.keySet()) {
					AccountEntity accountEntity = GameServer.accountEntityService.getAccount(teamMemberAcc);
					if (accountEntity != null) {
						AccountEntity proxyAccount = entityProxyFactory.createProxyEntity(accountEntity);
						proxyAccount.setMissionId(0);
						proxyAccount.setTeamId(0);
						if (!GameServer.accountEntityService.updateAccount(proxyAccount)) {
							logger.error("TeamService joinTeam updateAccount() Filed ! accountEntity={}",
									accountEntity.toString());
						}
					}
				}
				GameServer.teamEntityService.deleteTeam(teamEntity);
				//battleServer 删除房间
				GBTmpDestoryRoomREQ.Builder sendBuilder = GBTmpDestoryRoomREQ.newBuilder();
				sendBuilder.setTeamId(teamId);
				sendBuilder.setMissionId(missionId);
				ServerService service = ServiceContainer.getInstance().getPublicService(ServerService.class);
				this.sendMesToRemoteNode(service.getBattleNode(2000), sendBuilder.build());
			}
		} catch (Exception e) {
			// e.printStackTrace();
			logger.error("TeamService leaveTeam updateTeam() Filed ! Exception err={}", e.toString());
		}
	}
}
